package handler

import (
	"fmt"
	"time"
	"strconv"
	"strings"
	"net/http"

	"github.com/gorilla/mux"

	"read.com/wxmp/api"
	"read.com/wxmp/dao"
	"read.com/wxmp/util"
)

type UserOpenId struct {
	UserId    string `xorm:"not null CHAR(8)"`
	AppId     int    `xorm:"not null INT(11)"`
	OpenId    string `xorm:"not null VARCHAR(128)"`
	Sex       int    `xorm:"not null TINYINT(4)"`
	BookId    int    `xorm:"not null INT(11)"`
	ChapterId string `xorm:"not null TEXT"`
}

type UserSpread struct {
	UserId    string `xorm:"not null CHAR(8)"`
	AppId     int    `xorm:"not null INT(11)"`
	OpenId    string `xorm:"not null VARCHAR(128)"`
}

type ActicleItem struct {
	Title 		string 		`json:"title"`
	Description string 		`json:"description"`
	Url 		string 		`json:"url"`
	Picurl 		string 		`json:"picurl"`
}

type ImgTextMsg struct {
	Touser 	string						`json:"touser"`
	Msgtype string						`json:"msgtype"`
	News 	map[string][]ActicleItem 	`json:"news"`
}
// 未支付订单文字提示配置
var (
	activity = "c5200_a520_18" // 限时优惠活动
	limit    = "c3000_d30"     // 30限购礼包
	duration = 30             // 时间阈值
)

func registerInternalHandler(r *mux.Router) {
	r.Host("127.0.0.1").Methods(http.MethodGet).Path("/api/sign/{type:new|daily}").HandlerFunc(apiSignHandler)
	r.Host("127.0.0.1").Methods(http.MethodGet).Path("/api/unpay").HandlerFunc(apiUnpayHandler)
	r.Host("127.0.0.1").Methods(http.MethodGet).Path("/api/recommend").HandlerFunc(apiRecommendHandler)
	r.Host("127.0.0.1").Methods(http.MethodGet).Path("/api/pay/spread").HandlerFunc(apiSpreadHandler)
}

// http://127.0.0.1:9000/api/sign/daily?app=1&uid=10894850&coin=20&coin_next=50&no=2
func apiSignHandler(w http.ResponseWriter, r *http.Request) {
	app, _ := strconv.Atoi(r.FormValue("app"))
	appObj := dao.GetAppById(app)
	if appObj == nil {
		w.Write([]byte("app not found"))
		return
	}
	token := api.GetAccessToken(appObj.Id)
	if token == "" {
		w.Write([]byte("token not found"))
		return
	}

	uid := r.FormValue("uid")
	db := dao.GetSession()
	defer db.Close()

	// 查询用户
	userWxmp := &dao.UserWxmp{
		UserId: uid,
	}
	if has, err := db.Cols("union_id").Get(userWxmp); err != nil {
		fmt.Println("select user_wxmp error.", err)
		w.Write([]byte("db error"))
		return
	} else if !has {
		w.Write([]byte("user_wxmp not found"))
		return
	}
	userUnion := &dao.UserUnion{
		AppId:     appObj.Id,
		UnionId:   userWxmp.UnionId,
		Subscribe: 1,
	}
	onlineTime := time.Now().Add(-48 * time.Hour).Format("2006-01-02 15:04:05")
	if has, err := db.Where("online_date > ?", onlineTime).Get(userUnion); err != nil {
		fmt.Println("select user_union error.", err)
		w.Write([]byte("db error"))
		return
	} else if !has {
		w.Write([]byte("user_union not found"))
		return
	}

	// 查询阅读记录
	recRead := &dao.RecReading{
		UserId: uid,
	}
	chapList := make([]string, 0)
	bookList := make([]string, 0)
	if has, err := db.Get(recRead); err != nil {
		fmt.Println("select rec_reading error.", err)
		w.Write([]byte("db error"))
		return
	} else if !has {
		w.Write([]byte("rec not found"))
		return
	} else {
		chapId, _ := util.SliceAtoi(strings.Split(recRead.ChapterId, ","))
		bookId, _ := util.SliceAtoi(strings.Split(recRead.BookId, ","))
		if len(chapId) > 3 {
			bookId = bookId[0:3]
			chapId = chapId[0:3]
		}
		// 查询章节
		chapHash := map[int]*dao.BookChapter{}
		if err := db.Cols("id", "serial_id").In("id", chapId).Find(chapHash); err != nil {
			fmt.Println("select book_chapter error.", err)
			w.Write([]byte("db error"))
			return
		}
		// 查询书
		for i := 0; i < len(chapId); i++ {
			chapList = append(chapList, chapHash[chapId[i]].SerialId)
			bookList = append(bookList, dao.GetBookById(bookId[i]).Name)
		}
	}
	if len(chapList) == 0 {
		w.Write([]byte("list null"))
		return
	}

	coin := r.FormValue("coin")
	coinNext := r.FormValue("coin_next")
	builder := util.NewStringBuilder("🎉🎉")
	if mux.Vars(r)["type"] == "daily" {
		// 每日签到
		builder.AppendString("今日签到成功，获赠").AppendString(coin).AppendString("书币，")
		builder.AppendString("明日继续签到得").AppendString(coinNext).AppendString("书币哦~")
	} else {
		// 新手签到
		builder.AppendString("新用户第").AppendString(r.FormValue("no")).AppendString("次签到成功，获赠🎁").AppendString(coin).AppendString("书币")
		if coinNext != "" {
			builder.AppendString("，明日继续签到得").AppendString(coinNext).AppendString("书币哦~")
		}
	}
	builder.AppendString("\n\n")
	// 点我继续阅读
	builder.AppendHtmlHref(appObj.GetAppUrl("/view/home/last/chap/"), "点我继续阅读").AppendString("\n\n")
	// 阅读记录
	builder.AppendString("📖阅读记录：\n\n")
	for i := 0; i < len(chapList); i++ {
		name := bookList[i]
		chap := chapList[i]
		builder.AppendString(" > ")
		builder.AppendHtmlHref(appObj.GetAppUrl("/view/home/chapter/"+chap+"/"), name).AppendString("\n\n")
	}
	builder.AppendString("去看更多").AppendHtmlHref(appObj.GetAppUrl("/view/home/menu/listdetail/")+"?type=热门小说", "热门小说").AppendString("👀")
	// 通过客服接口，给用户发消息
	go api.SendCustomMessage(token, userUnion.OpenId, builder.String())

	w.Write([]byte("success"))
}

// 未支付回复消息
func apiUnpayHandler(w http.ResponseWriter, r *http.Request) {
	app, _ := strconv.Atoi(r.FormValue("app"))
	appObj := dao.GetAppById(app)
	if appObj == nil {
		w.Write([]byte("app not found"))
		return
	}
	token := api.GetAccessToken(appObj.Id)
	if token == "" {
		w.Write([]byte("token not found"))
		return
	}

	uid := r.FormValue("uid")
	db := dao.GetSession()
	defer db.Close()

	// 查询用户
	userWxmp := &dao.UserWxmp{
		UserId: uid,
	}
	if has, err := db.Cols("union_id").Get(userWxmp); err != nil {
		fmt.Println("select user_wxmp error.", err)
		w.Write([]byte("db error"))
		return
	} else if !has {
		w.Write([]byte("user_wxmp not found"))
		return
	}
	userUnion := &dao.UserUnion{
		AppId:     appObj.Id,
		UnionId:   userWxmp.UnionId,
		Subscribe: 1,
	}
	onlineTime := time.Now().Add(-48 * time.Hour).Format("2006-01-02 15:04:05")
	if has, err := db.Where("online_date > ?", onlineTime).Get(userUnion); err != nil {
		fmt.Println("select user_union error.", err)
		w.Write([]byte("db error"))
		return
	} else if !has {
		w.Write([]byte("user_union not found"))
		return
	}

	//①线上有优惠活动：限时活动【充52即送5200书币】
	//②从未充值用户：首充加送1000书币
	//③当前未充值30礼包：限购活动【充30 累计可得8800书币】
	//④当前已购30礼包：特惠活动【包月VIP买一赠一，全站小说免费看】
	//⑤当前状态为VIP包月：实用推荐【包年VIP：全年免费看小说，每天只需一块钱】

	str := ""
	// 判断是否为VIP包月
	user := &dao.User{
		UserId: uid,
	}
	if has, err := db.Get(user); err != nil {
		fmt.Println("select user error", err)
		return
	} else if !has {
		fmt.Println("user not found")
		return
	} else {
		if user.VipEnd.Unix() > time.Now().Unix() {
			str = "实用推荐【包年VIP：全年免费看小说，每天只需一块钱】，"
		}
	}

	// 判断是否充值过30礼包 limit
	payItem := &dao.PayItem{
		Code: limit,
	}
	if has, err := db.Get(payItem); err != nil {
		fmt.Println("select pay_item err", err)
		return
	} else if !has {
		fmt.Println("pay_item not found")
		return
	} else {
		payConfirm := &dao.PayConfirm{
			UserId: uid,
			ItemId: payItem.Id,
		}
		if has, err := db.Get(payConfirm); err != nil {
			fmt.Println("select pay_confirm error", err)
			return
		} else if !has {
			// 没充过
			str = "限购活动【充" + strconv.Itoa(payItem.Price/100) + " 累计可得" + strconv.Itoa(payItem.Coin+payItem.Extra*payItem.ExtraDay) + "书币】，"
			return
		} else {
			// 充值过
			str = "特惠活动【包月VIP买一赠一，全站小说免费看】，"
		}
	}

	// 判断是否为首充
	if user.PayCnt == 0 {
		str = "首充加送1000书币，"
	}

	// 判断是否有活动 activity
	payItem = &dao.PayItem{
		Code: activity,
	}
	if has, err := db.Get(payItem); err != nil {
		fmt.Println("select pay_item err", err)
		return
	} else if !has {
		fmt.Println("pay_item not found")
		return
	} else {
		str = "限时活动【充" + strconv.Itoa(payItem.Price/100) + "即送" + strconv.Itoa(payItem.Coin) + "书币】，"
	}

	builder := util.NewStringBuilder("书币订单未支付提醒：\n\n")
	builder.AppendString("亲，您的书币订单还未支付，小说后续剧情高潮迭起，")
	builder.AppendString(str)
	builder.AppendString("赶紧行动吧！\n\n")
	builder.AppendHtmlHref("/view/home/menu/rechargebook/", "点击充值")
	go api.SendCustomMessage(token, userUnion.OpenId, builder.String())
}

// 推送继续阅读+小说推荐的图文链接
func apiRecommendHandler(w http.ResponseWriter, r *http.Request) {
	db := dao.GetSession()
	defer db.Close()

	start := time.Now().AddDate(0, 0, -1).Format("2006-01-02") + " 00:00:00"
	end := time.Now().Format("2006-01-02") + " 00:00:00"

	userList := make([]*UserOpenId, 0)
	sql := "SELECT a.user_id, b.app_id, b.open_id, b.sex, c.chapter_id, c.book_id " +
		"FROM user_wxmp a " +
		"INNER JOIN user_union b ON(a.union_id = b.union_id AND b.subscribe = 1 AND b.online_date > ? AND b.online_date < ?) " +
		"INNER JOIN rec_reading c ON(a.user_id = c.user_id)"
	db.SQL(sql, start, end).Find(&userList)

	for _, user := range userList {
		lastReadPic := dao.GetBookById(user.BookId).OssUrl
		lastReadId, err := strconv.Atoi(strings.Split(user.ChapterId, ",")[0])
		if err != nil {
			fmt.Println("string to int error", err)
		}
		lastReadUrl := ""
		bookChapter := &dao.BookChapter{
			Id: lastReadId,
		}
		if has, err := db.Cols("serial_id").Get(bookChapter); err != nil {
			fmt.Println("select book_chapter error", err)
		} else if !has {
			fmt.Println("serial_id not found")
		} else {
			lastReadUrl = dao.GetAppById(user.AppId).GetAppUrl("/view/home/chapter/" + bookChapter.SerialId + "/")
		}

		articleList := make([]ActicleItem,0)

		// 若阅读过小说，将最近阅读取出
		if user.ChapterId != "" {
			lastReadActicleItem := ActicleItem{
				Title:"继续阅读",
				Url:lastReadUrl,
				Picurl:lastReadPic,
			}
			articleList = append(articleList, lastReadActicleItem)
		}

		// 根据性别加四本推荐小说
		hotBookList := dao.GetHotBook(user.Sex)[0:4]
		for _, book := range hotBookList {
			articleItem := ActicleItem{
				Title:book.Name,
				Url:dao.GetAppById(user.AppId).GetAppUrl("/view/home/book/" + book.SerialId + "/"),
				Picurl:book.OssUrl,
			}
			articleList = append(articleList, articleItem)
		}
		acticleListMap := map[string][]ActicleItem{
			"articles": articleList,
		}
		imgTextMsg := ImgTextMsg{
			Touser:  user.OpenId,
			Msgtype: "news",
			News:    acticleListMap,
		}
		go api.SendImgMsg(api.GetAccessToken(user.AppId),imgTextMsg)
	}
}

// 支付推广 图文链接
func apiSpreadHandler(w http.ResponseWriter, r *http.Request){
	db := dao.GetSession()
	defer db.Close()

	start := time.Now().Add(-time.Minute*time.Duration(duration)).Format("2006-01-02 15:04:05")
	end := time.Now().Format("2006-01-02 15:04:05")

	userSpreads := make([]*UserSpread, 0)
	sql := "SELECT a.user_id, b.open_id, b.app_id" +
		"FROM user_wxmp a " +
		"INNER JOIN user_union b ON(a.union_id = b.union_id AND b.subscribe = 1 AND b.login_date >= ? AND b.login_date < ?) "
	db.SQL(sql, start, end).Find(&userSpreads)

	for _, userSpread := range userSpreads {
		articleList := make([]ActicleItem,0)
		acticleListMap := map[string][]ActicleItem{
			"articles": articleList,
		}
		imgTextMsg := ImgTextMsg{
			Touser:  userSpread.OpenId,
			Msgtype: "news",
			News:    acticleListMap,
		}


		user := &dao.User{
			UserId: userSpread.UserId,
		}
		if has, err := db.Get(user); err != nil {
			fmt.Println("select user error", err)
			return
		} else if !has {
			fmt.Println("user not found")
			return
		} else {
			// 未充值过
			if user.PayCnt == 0 {
				// todo 首充送1000，链接充值页
				articleItem := ActicleItem{
					Title:"",
					Url:"",
					Picurl:"",
				}
				articleList = append(articleList, articleItem)
			}else {
				// 判断是否充值过 30 礼包
				payItem := &dao.PayItem{
					Code: limit,
				}
				if has, err := db.Get(payItem); err != nil {
					fmt.Println("select pay_item err", err)
					return
				} else if !has {
					fmt.Println("pay_item not found")
					return
				} else {
					payConfirm := &dao.PayConfirm{
						UserId: user.UserId,
						ItemId: payItem.Id,
					}
					if has, err := db.Get(payConfirm); err != nil {
						fmt.Println("select pay_confirm error", err)
						return
					} else if !has {
						// 没充过 30 礼包
						// todo 30限购礼包推广，链接直接支付
						articleItem := ActicleItem{
							Title:"",
							Url:"",
							Picurl:"",
						}
						articleList = append(articleList, articleItem)
					} else {
						// 充值过 30 礼包  再判断当前状态是否为VIP包月
						// 是包月状态
						if user.VipEnd.Unix() > time.Now().Unix() {
							// todo 包年推广，链接直接支付
							articleItem := ActicleItem{
								Title:"",
								Url:"",
								Picurl:"",
							}
							articleList = append(articleList, articleItem)
						}else {
							// todo 包月推广，链接直接支付
							articleItem := ActicleItem{
								Title:"",
								Url:"",
								Picurl:"",
							}
							articleList = append(articleList, articleItem)
						}
					}
				}
			}
		}
		// 判断是否有活动 activity
		payItem := &dao.PayItem{
			Code: activity,
		}
		if has, err := db.Get(payItem); err != nil {
			fmt.Println("select pay_item err", err)
			return
		} else if !has {
			fmt.Println("pay_item not found")
			return
		} else {
			// todo 线上有限时活动：限时活动推广，链接直接支付
			articleItem := ActicleItem{
				Title:"",
				Url:"",
				Picurl:"",
			}
			// 先清空，再追加
			articleList = articleList[len(articleList):]
			articleList = append(articleList, articleItem)
		}
		go api.SendImgMsg(api.GetAccessToken(userSpread.AppId),imgTextMsg)
	}
}
